// 导入本地模块
const path = require('path');
const { customRequire } = require('../utils.js');
const config = require('../config');
const manifest = require('../manifest.json');
const { log, error, cleanupModuleData } = require('../utils.js');
const pathUtils = require('../utils/path-utils');

// 设置全局错误处理器
process.on('uncaughtException', (err) => {
    console.error('未捕获的异常:', err);
    console.error('错误堆栈:', err.stack);
    error('未捕获的异常: ' + err.message, err);
    log('发生未捕获的异常: ' + err.message);
});

process.on('unhandledRejection', (reason, promise) => {
    console.error('未处理的Promise拒绝:', reason);
    if (reason instanceof Error) {
        console.error('错误堆栈:', reason.stack);
        error('未处理的Promise拒绝: ' + reason.message, reason);
        log('发生未处理的Promise拒绝: ' + reason.message);
    } else {
        error('未处理的Promise拒绝: ' + reason);
        log('发生未处理的Promise拒绝: ' + reason);
    }
});

// 导入外部模块
log('正在导入playwright模块...');
const { chromium } = customRequire('playwright');
log('正在导入fs模块...');
const fs = require('fs');

// 记录配置信息
log(`插件版本: ${manifest.version}`);
log(`配置加载完成: 浏览器超时=${config.browser.timeout}ms, 重试次数=${config.retry.maxRetries}`);

// 定义需要匹配的ASTM委员会
const targetCommittees = [
    { id: 'F06', name: 'Resilient Floor Coverings' },
    { id: 'F08', name: 'Sports Equipment, Playing Surfaces, and Facilities' },
    { id: 'F15', name: 'Consumer Products' }
];

// 全局变量，用于存储当前浏览器实例，以便在中断时关闭
let currentBrowser = null;

async function scrapeAstmUpdates(isHeadless, signal) {
    // 记录开始信息
    log(`开始执行 ASTM 标准更新数据抓取任务`, 'info');
    log(`目标委员会: ${targetCommittees.length} 个`, 'info');
    
    // 检查是否已经被中止
    if (signal && signal.aborted) {
        log('任务已被用户取消', 'warning');
        throw new Error('任务已被用户取消');
    }
    
    log('启动浏览器...');
    log('浏览器配置: ' + (isHeadless ? '隐藏模式' : '显示模式') + ', 超时: ' + config.browser.timeout + 'ms');
    const browser = await chromium.launch({ 
        // 注意：这里需要反转isHeadless参数
        // 原因：在UI中，isHeadless=false表示"隐藏"模式，但在playwright中，headless=true才表示隐藏模式
        // 因此，当UI设置为"隐藏"(isHeadless=false)时，我们需要将headless设为true
        // 当UI设置为"显示"(isHeadless=true)时，我们需要将headless设为false
        headless: !isHeadless,
        timeout: config.browser.timeout,
        args: ['--start-maximized', '--disable-features=IsolateOrigins,site-per-process'],
        executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
    });
    log('浏览器启动成功，使用' + (isHeadless ? '隐藏模式' : '显示模式'));
    
    // 存储浏览器实例，以便在中断时关闭
    currentBrowser = browser;
    
    // 如果信号存在，添加中断处理
    if (signal) {
        log('已设置中断信号处理器', 'info');
        signal.addEventListener('abort', async () => {
            log('收到中断信号，正在关闭浏览器...', 'warning');
            if (currentBrowser) {
                try {
                    await currentBrowser.close();
                    log('浏览器已关闭（由中断信号触发）', 'info');
                } catch (err) {
                    console.error('关闭浏览器时出错:', err);
                    log(`关闭浏览器时出错: ${err.message}`, 'error');
                }
                currentBrowser = null;
            }
        });
    }
    
    const context = await browser.newContext({ viewport: null, userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' });
    log('创建浏览器上下文成功', 'info');
    const page = await context.newPage();
    log('创建新页面成功', 'info');
    
    // 设置默认超时时间
    page.setDefaultTimeout(config.browser.defaultTimeout);
    log(`设置页面默认超时时间: ${config.browser.defaultTimeout}ms`, 'info');
    
    // 创建数组来收集所有数据
    const allData = [];
    
    try {
        log('开始访问ASTM网站...');
        
        log(`正在导航到ASTM委员会页面...`);
        log(`页面加载超时设置: ${config.browser.pageLoadTimeout}ms`);
        try {
            await page.goto('https://www.astm.org/membership-participation/technical-committees/committee-all', {
                // waitUntil: 'networkidle', // 等待网络空闲
                timeout: config.browser.pageLoadTimeout
            });
            log('页面导航成功，ASTM网站已加载');
        } catch (navigationError) {
            console.error(`页面导航失败: ${navigationError.message}`);
            error(`页面导航失败: ${navigationError.message}`, navigationError);
            log('首次导航失败，尝试使用不同的等待策略重新导航...', 'warning');
            
            try {
                await page.goto('https://www.astm.org/membership-participation/technical-committees/committee-all', {
                    waitUntil: 'domcontentloaded', // 仅等待DOM加载完成
                    timeout: config.browser.pageLoadTimeout
                });
                log('使用domcontentloaded策略导航成功', 'info');
            } catch (retryError) {
                console.error(`重试导航失败: ${retryError.message}`);
                error(`重试导航失败: ${retryError.message}`, retryError);
                log(`重试导航失败: ${retryError.message}`, 'error');
                throw new Error(`无法访问ASTM网站: ${retryError.message}`);
            }
        }
        
        // 检查是否需要点击"Stay on astm.org"按钮
        try {
            const stayButton = await page.$('button:has-text("Stay on astm.org")');
            if (stayButton) {
                log('找到"Stay on astm.org"按钮，点击它...');
                await stayButton.click();
                log('已点击"Stay on astm.org"按钮');
                await page.waitForTimeout(1000); // 等待按钮点击后的页面变化
            }
        } catch (stayButtonError) {
            log('没有找到"Stay on astm.org"按钮或点击失败，继续执行...', 'info');
        }
        
        // 处理每个目标委员会
        for (const committee of targetCommittees) {
            if (signal && signal.aborted) {
                log('任务已被用户取消', 'warning');
                break;
            }
            
            log(`处理委员会: ${committee.id} - ${committee.name}`);
            
            // 在页面上查找committee链接
            const committeeSelector = `a:has-text("${committee.id} - ${committee.name}")`;
            try {
                // 等待committee链接出现 - 增加超时时间以适应无头模式
                log(`等待委员会链接出现: ${committeeSelector}`);
                await page.waitForSelector(committeeSelector, { timeout: 30000 });
                
                // 在新标签页中打开committee链接
                const [newPage] = await Promise.all([
                    context.waitForEvent('page'),
                    page.click(committeeSelector, { button: 'middle' }) // 中键点击，在新标签页打开
                ]);
                
                if (!newPage) {
                    throw new Error(`打开委员会 ${committee.id} 链接失败，未能获取新页面`);
                }
                
                log(`已在新标签页中打开委员会 ${committee.id}`);
                
                // await newPage.waitForTimeout(5000);
                // 获取页面内容
                // const textContent = await newPage.textContent('body');
                
                
                // 在委员会页面中查找"List of Subcommittees, Standards, and Work Items"链接
                try {
                    const listLinkSelector = 'a:has-text("List of Subcommittees, Standards, and Work Items")';
                    log(`等待链接出现: ${listLinkSelector}`);
                    await newPage.waitForSelector(listLinkSelector, { timeout: 30000 });
                    
                    // 点击链接
                    await newPage.click(listLinkSelector);
                    log(`已点击"List of Subcommittees, Standards, and Work Items"链接`);
                    // await newPage.waitForTimeout(3000);

                    // 在data-testid="juridiction-text"的div中查找链接
                    await newPage.waitForSelector('div[data-testid="juridiction-text"]', { timeout: 10000 });
                    const juridictionDiv = await newPage.$('div[data-testid="juridiction-text"]');
                    if (juridictionDiv) {
                        log(`找到Standards under the jurisdiction，开始查找链接`);
                        // 在juridictionDiv中查找所有链接
                        const juridictionLinks = await juridictionDiv.$$('a');
                        log(`Standards under the jurisdiction有 ${juridictionLinks.length} 个链接`);
                        
                        // 处理juridictionDiv中的每个链接
                        for (const juridictionLink of juridictionLinks) {
                            if (signal && signal.aborted) {
                                log('任务已被用户取消', 'warning');
                                break;
                            }
                            
                            // 获取链接文本
                            const juridictionLinkText = await juridictionLink.textContent();
                            log(`处理juridictionDiv中的链接: ${juridictionLinkText}`);
                            
                            // 在新标签页中打开链接
                            const [subcommitteePage] = await Promise.all([
                                context.waitForEvent('page'),
                                juridictionLink.click({ button: 'middle' }) // 中键点击，在新标签页打开
                            ]);
                            
                            if (!subcommitteePage) {
                                throw new Error(`打开子委员会链接 ${juridictionLinkText} 失败，未能获取新页面`);
                            }
                            
                            log(`已在新标签页中打开子委员会页面: ${juridictionLinkText}`);
                            // await subcommitteePage.waitForTimeout(10000);
                            
                            // 在新打开的页面中查找第一个class="accordion-body"的div
                            await subcommitteePage.waitForSelector('div.accordion-body', { timeout: 10000 });
                            const accordionBody = await subcommitteePage.$('div.accordion-body');
                            if (accordionBody) {
                                log(`找到class="accordion-body"的div，开始查找链接`);
                                // 在accordionBody中查找所有li中的链接
                                const accordionLinks = await accordionBody.$$('li a');
                                log(`在accordionBody中找到 ${accordionLinks.length} 个链接`);
                                
                                // 处理accordionBody中的每个链接
                                for (const accordionLink of accordionLinks) {
                                    if (signal && signal.aborted) {
                                        log('任务已被用户取消', 'warning');
                                        break;
                                    }
                                    
                                    // 获取链接文本
                                    const accordionLinkText = await accordionLink.textContent();
                                    
                                    // 检查链接是否包含'-25'
                                    if (accordionLinkText.includes('-25')) {
                                        log(`找到包含'-25'的链接: ${accordionLinkText}`);
                                        
                                        // 在新标签页中打开链接
                                        const [standardPage] = await Promise.all([
                                            context.waitForEvent('page'),
                                            accordionLink.click({ button: 'middle' }) // 中键点击，在新标签页打开
                                        ]);
                                        
                                        if (!standardPage) {
                                            throw new Error(`打开标准链接 ${accordionLinkText} 失败，未能获取新页面`);
                                        }
                                        
                                        log(`已在新标签页中打开标准页面: ${accordionLinkText}`);
                                        await standardPage.waitForSelector('#standards_header', { timeout: 10000 });
                                        // await standardPage.waitForTimeout(10000);
                                        
                                        // 提取标准信息
                                        try {
                                            // 查找Last Updated信息 - 通过standards_header定位
                                            const lastUpdated = await standardPage.evaluate(() => {
                                                // 先找到id="standards_header"的div
                                                const headerDiv = document.getElementById('standards_header');
                                                if (headerDiv) {
                                                    // 在headerDiv中查找所有span元素
                                                    const spans = headerDiv.querySelectorAll('span');
                                                    // 遍历所有span，查找包含Last Updated:的元素
                                                    for (const span of spans) {
                                                        if (span.textContent && span.textContent.includes('Last Updated:')) {
                                                            // 提取文本并去除"Last Updated:"部分
                                                            const text = span.textContent.trim();
                                                            return text.replace('Last Updated:', '').trim();
                                                        }
                                                    }
                                                }
                                                // 如果没有找到，尝试使用备用方法
                                                const elements = Array.from(document.querySelectorAll('*'));
                                                for (const element of elements) {
                                                    const text = element.textContent;
                                                    if (text && text.includes('Last Updated:')) {
                                                        const match = text.match(/Last Updated:\s*([\w\s,]+)/);
                                                        if (match && match[1]) {
                                                            return match[1].trim();
                                                        }
                                                        return text.replace('Last Updated:', '').trim();
                                                    }
                                                }
                                                return null;
                                            });
                                            
                                            // 查找标准号
                                            const standardNumber = await standardPage.evaluate(() => {
                                                const div = document.querySelector('.mt-4.standards-main-content-tracker');
                                                if (div) {
                                                    const b = div.querySelector('b');
                                                    if (b) {
                                                        return b.textContent.trim();
                                                    }
                                                }
                                                return null;
                                            });
                                            
                                            // 查标准名称
                                            const standardName = await standardPage.evaluate(() => {
                                                const div = document.querySelector('.astm-type-heading--h3.mt-0');
                                                if (div) {
                                                    const b = div.querySelector('b');
                                                    if (b) {
                                                        return b.textContent.trim();
                                                    }
                                                }
                                                return null;
                                            });

                                            // 查找版本号
                                            const version = await standardPage.evaluate(() => {
                                                const div = document.querySelector('.astm-dropdown.dropdown.versions.versions-dropdown');
                                                if (div) {
                                                    // 版本号在button内的a标签中
                                                    const versionLink = div.querySelector('button a');
                                                    if (versionLink) {
                            
                                                        const text = versionLink.textContent.trim();
                                                        // 移除可能的Active标记
                                                        return text.replace(/\s+Active$/, '').trim();
                                                    }
                                                }
                                                return null;
                                            });
                                            
                                            // 查找上一个版本号（下拉菜单中的第一个选项）
                                            const lastversion = await standardPage.evaluate(() => {
                                                const div = document.querySelector('.astm-dropdown.dropdown.versions.versions-dropdown');
                                                if (div) {
                                                    // 查找下拉菜单中的第一个选项
                                                    const firstOption = div.querySelector('.dropdown-menu .dropdown-item:first-child a');
                                                    if (firstOption) {
                                                        return firstOption.textContent.trim();
                                                    }
                                                }
                                                return null;
                                            });
                                            
                                            if (standardNumber || lastUpdated || version) {
                                                const standardData = {
                                                    region: 'USA',
                                                    standard: standardNumber,
                                                    standardName: standardName,
                                                    dateOfPublication: lastUpdated,
                                                    brief: lastversion ? `${version} supersedes ${lastversion}` : '',
                                                    url: standardPage.url(),
                                                    version: version,
                                                    lastversion: lastversion,
                                                    committee: committee.id,
                                                };
                                                
                                                log(`提取的标准信息: ${standardNumber}, 版本: ${version}, 上一版本: ${lastversion}, 更新日期: ${lastUpdated}`);
                                                
                                                allData.push(standardData);
                                            }
                                            
                                            // 关闭标准页面
                                            await standardPage.close();
                                            log(`已关闭标准页面`);
                                        } catch (extractError) {
                                            console.error(`提取标准信息时出错: ${extractError.message}`);
                                            error(`提取标准信息时出错: ${extractError.message}`, extractError);
                                            log(`提取标准信息时出错: ${extractError.message}`, 'error');
                                            
                                            // 关闭标准页面
                                            await standardPage.close();
                                            log(`已关闭标准页面`);
                                        }
                                    }
                                }
                            } else {
                                log(`未找到class="accordion-body"的div`, 'warning');
                            }
                            
                            // 关闭子委员会页面
                            await subcommitteePage.close();
                            log(`已关闭子委员会页面`);
                        }
                    } else {
                        log(`未找到data-testid="juridiction-text"的div，尝试使用原始方法查找链接`, 'warning');
                        // 使用原始方法查找链接
                        const links = await newPage.$$('li a');
                        log(`找到 ${links.length} 个链接`);
                        
                        // 处理每个链接
                        for (const link of links) {
                            if (signal && signal.aborted) {
                                log('任务已被用户取消', 'warning');
                                break;
                            }
                            
                            // 获取链接文本
                            const linkText = await link.textContent();
                            
                            // 检查链接是否包含'-25'
                            if (linkText.includes('-25')) {
                                log(`找到包含'-25'的链接: ${linkText}`);
                                
                                // 在新标签页中打开链接
                                const [standardPage] = await Promise.all([
                                    context.waitForEvent('page'),
                                    link.click({ button: 'middle' }) // 中键点击，在新标签页打开
                                ]);
                                
                                if (!standardPage) {
                                    throw new Error(`打开标准链接 ${linkText} 失败，未能获取新页面`);
                                }
                                
                                log(`已在新标签页中打开标准页面: ${linkText}`);
                                await standardPage.waitForSelector('#standards_header', { timeout: 10000 });
                                // await standardPage.waitForTimeout(10000);
                                
                                // 提取标准信息
                                try {
                                    // 查找Last Updated信息 - 通过standards_header定位
                                    const lastUpdated = await standardPage.evaluate(() => {
                                        // 先找到id="standards_header"的div
                                        const headerDiv = document.getElementById('standards_header');
                                        if (headerDiv) {
                                            // 在headerDiv中查找所有span元素
                                            const spans = headerDiv.querySelectorAll('span');
                                            // 遍历所有span，查找包含Last Updated:的元素
                                            for (const span of spans) {
                                                if (span.textContent && span.textContent.includes('Last Updated:')) {
                                                    // 提取文本并去除"Last Updated:"部分
                                                    const text = span.textContent.trim();
                                                    return text.replace('Last Updated:', '').trim();
                                                }
                                            }
                                        }
                                        // 如果没有找到，尝试使用备用方法
                                        const elements = Array.from(document.querySelectorAll('*'));
                                        for (const element of elements) {
                                            const text = element.textContent;
                                            if (text && text.includes('Last Updated:')) {
                                                const match = text.match(/Last Updated:\s*([\w\s,]+)/);
                                                if (match && match[1]) {
                                                    return match[1].trim();
                                                }
                                                return text.replace('Last Updated:', '').trim();
                                            }
                                        }
                                        return null;
                                    });
                                    
                                    // 查找标准号
                                    const standardNumber = await standardPage.evaluate(() => {
                                        const div = document.querySelector('.mt-4.standards-main-content-tracker');
                                        if (div) {
                                            const b = div.querySelector('b');
                                            if (b) {
                                                return b.textContent.trim();
                                            }
                                        }
                                        return null;
                                    });
                                    
                                    // 查找版本号
                                    const version = await standardPage.evaluate(() => {
                                        const div = document.querySelector('.astm-dropdown.dropdown.versions.versions-dropdown');
                                        if (div) {
                                            // 版本号在button内的a标签中
                                            const versionLink = div.querySelector('button a');
                                            if (versionLink) {
                                                // 提取文本并清理
                                                const text = versionLink.textContent.trim();
                                                // 移除可能的Active标记
                                                return text.replace(/\s+Active$/, '').trim();
                                            }
                                        }
                                        return null;
                                    });
                                    
                                    // 查找上一个版本号（下拉菜单中的第一个选项）
                                    const lastversion = await standardPage.evaluate(() => {
                                        const div = document.querySelector('.astm-dropdown.dropdown.versions.versions-dropdown');
                                        if (div) {
                                            // 查找下拉菜单中的第一个选项
                                            const firstOption = div.querySelector('.dropdown-menu .dropdown-item:first-child a');
                                            if (firstOption) {
                                                return firstOption.textContent.trim();
                                            }
                                        }
                                        return null;
                                    });
                                    
                                    if (standardNumber || lastUpdated || version) {
                                        const standardData = {
                                            region: 'USA',
                                            standard: standardNumber,
                                            // standardName: standardName,
                                            dateOfPublication: lastUpdated,
                                            brief: lastversion ? `${version} supersedes ${lastversion}` : '',
                                            url: standardPage.url(),
                                            version: version,
                                            lastversion: lastversion,
                                            committee: committee.id,
                                        };
                                        
                                        log(`提取的标准信息: ${standardNumber}, 版本: ${version}, 上一版本: ${lastversion}, 更新日期: ${lastUpdated}`);
                                        
                                        allData.push(standardData);
                                    }
                                } catch (extractError) {
                                    console.error(`提取标准信息时出错: ${extractError.message}`);
                                    error(`提取标准信息时出错: ${extractError.message}`, extractError);
                                    log(`提取标准信息时出错: ${extractError.message}`, 'error');
                                }
                                
                                // 关闭标准页面
                                await standardPage.close();
                                log(`已关闭标准页面`);
                            }
                        }
                    }
                    // 关闭委员会页面
                    await newPage.close();
                    log(`已关闭委员会 ${committee.id} 页面`);
                } catch (committeeError) {
                    console.error(`查找或点击委员会 ${committee.id} 链接时出错: ${committeeError.message}`);
                    error(`查找或点击委员会 ${committee.id} 链接时出错: ${committeeError.message}`, committeeError);
                    log(`查找或点击委员会 ${committee.id} 链接时出错: ${committeeError.message}`, 'error');
                }
            } catch (error) {
                console.error(`出现错误： ${error}`);
            }
        }
        
        // 保存数据到JSON文件
        if (allData.length > 0) {
            // 清理旧数据文件
            try {
                cleanupModuleData('astm');
            } catch (cleanupError) {
                log(`清理旧数据时出现警告: ${cleanupError.message}`, 'warning');
            }
            
            // 使用统一的数据路径管理
            const dataDir = pathUtils.getDataPath('astm');
            pathUtils.ensureDirectoryExists(dataDir);
            
            const filePath = path.join(dataDir, `astm_updates_${new Date().toISOString().slice(0, 10)}.json`);
            fs.writeFileSync(filePath, JSON.stringify(allData, null, 2));
            log(`数据已保存到文件: ${filePath}`, 'success');
        } else {
            log('没有找到符合条件的ASTM标准更新数据', 'warning');
        }
        
        return allData;
        
    } catch (error) {
        console.error(`ASTM标准更新数据抓取过程中发生错误: ${error.message}`);
        error(`ASTM标准更新数据抓取过程中发生错误: ${error.message}`, error);
        log(`ASTM标准更新数据抓取过程中发生错误: ${error.message}`, 'error');
        throw error;
    } finally {
        // 关闭浏览器
        if (currentBrowser) {
            try {
                await currentBrowser.close();
                log('浏览器已关闭', 'info');
            } catch (err) {
                console.error('关闭浏览器时出错:', err);
                log(`关闭浏览器时出错: ${err.message}`, 'error');
            }
            currentBrowser = null;
        }
    }
}

// 支持中断信号的函数
async function runWithSignal(signal, isHeadless) {
    try {
        // 检查信号是否已经被中止
        if (signal && signal.aborted) {
            console.log('任务已被取消');
            log('任务已被用户取消', 'warning');
            return { success: false, error: '任务已被用户取消' };
        }
        
        console.log('使用可中断模式启动任务...');
        log('使用可中断模式启动任务...', 'info');
        
        try {
            // 执行爬取任务并传递信号
            const data = await scrapeAstmUpdates(isHeadless, signal);
            return { success: true, data };
        } catch (err) {
            // 检查是否是由于中断导致的错误
            if (signal && signal.aborted) {
                console.log('任务已被用户取消');
                log('任务已被用户取消', 'warning');
                return { success: false, error: '任务已被用户取消' };
            }
            
            // 其他错误
            throw err;
        }
    } catch (err) {
        console.error(`任务执行失败: ${err.stack || err}`);
        log(`任务执行失败: ${err.stack || err}`, 'error');
        return { success: false, error: err.message || '任务执行失败' };
    }
}

// 主函数
async function main(isHeadless) {
    try {
        // 获取命令行参数
        const args = process.argv.slice(2);
        // 解析isHeadless参数
        // 从astm-update.js传入的isAstmHeadless.value
        // true: 表示浏览器应该显示
        // false: 表示浏览器应该隐藏（默认值）
        // const isHeadless = 'true';
        
        // 创建中止控制器
        const controller = new AbortController();
        const signal = controller.signal;
        
        // 设置中断处理
        process.on('SIGINT', () => {
            console.log('收到SIGINT信号，正在中止...');
            controller.abort();
        });
        
        // 执行爬取任务
        const data = await scrapeAstmUpdates(isHeadless, signal);
        
        // 返回结果
        return { success: true, data };
    } catch (error) {
        console.error(`执行失败: ${error.message}`);
        return { success: false, error: error.message };
    }
}

// 如果直接运行此脚本，则执行main函数
if (require.main === module) {
    main().then(result => {
        if (result.success) {
            console.log('ASTM标准更新数据抓取成功');
            process.exit(0);
        } else {
            console.error(`ASTM标准更新数据抓取失败: ${result.error}`);
            process.exit(1);
        }
    }).catch(err => {
        console.error(`执行过程中发生未捕获的错误: ${err.message}`);
        process.exit(1);
    });
} else {
    // 作为模块导出main函数
    module.exports = main;
    // 导出支持中断信号的函数
    module.exports.runWithSignal = runWithSignal;
}